const Koa = require('koa');
const Router = require('koa-router');
const httpProxy = require('http-proxy');
const vscode = require('vscode');
const { getCurrentAccount, getCurrentToken } = require('./refreshLogin');
const fs = require('fs');
const path = require('path');

// 获取项目文件路径
function getProjectFile(relativePath, workspacePath = null) {
    try {
        // 如果指定了工作区路径，使用指定的路径
        if (workspacePath) {
            return path.join(workspacePath, relativePath);
        }
        
        // 否则使用第一个工作区路径（向后兼容）
        if (!vscode.workspace.workspaceFolders || !vscode.workspace.workspaceFolders.length) {
            return null
        }
        const defaultWorkspacePath = vscode.workspace.workspaceFolders[0].uri.fsPath;
        return path.join(defaultWorkspacePath, relativePath);
    } catch (error) {
        return null;
    }
}

// 从.env文件读取端口配置
function getPortFromEnv(portKey, defaultPort, workspacePath = null) {
    const envPath = getProjectFile('.env', workspacePath)
    if (!envPath || !fs.existsSync(envPath)) return defaultPort

    const envData = fs.readFileSync(envPath, 'utf8');
    const portLine = envData.split('\n').find(line => line.startsWith(`${portKey}=`))
    if (!portLine) return defaultPort

    const port = parseInt(portLine.split('=')[1])
    return isNaN(port) ? defaultPort : port
}

// 保存端口配置到.env文件
function savePortToEnv(portKey, port, workspacePath = null) {
    const envPath = getProjectFile('.env', workspacePath)
    if (!envPath) return;
    
    let envData = '';
    if (fs.existsSync(envPath)) {
        envData = fs.readFileSync(envPath, 'utf8');
    }

    const lines = envData.split('\n');
    const portIndex = lines.findIndex(line => line.startsWith(`${portKey}=`));
    
    if (portIndex !== -1) {
        // 更新现有的端口
        lines[portIndex] = `${portKey}=${port}`;
    } else {
        // 添加新的端口配置
        lines.push(`${portKey}=${port}`);
    }

    // 确保文件以换行符结尾
    const newContent = lines.join('\n');
    fs.writeFileSync(envPath, newContent.endsWith('\n') ? newContent : newContent + '\n', 'utf8');
    
    console.log(`端口配置已保存到.env文件: ${portKey}=${port}`);
}

class ProxyServerManager {
    constructor(workspacePath = null) {
        this.app = null;
        this.server = null;
        this.proxy = httpProxy.createProxyServer();
        this.workspacePath = workspacePath;
        
        // 从.env文件读取端口配置，如果没有则使用默认端口3838
        this.port = getPortFromEnv('PROXY_SERVER_PORT', 3838, this.workspacePath);
        console.log(`代理服务器端口设置为: ${this.port} (工作区: ${this.workspacePath || 'default'})`);
    }

    setupKoaApp() {
        const app = new Koa();
        const router = new Router();

        // 代理处理中间件
        app.use(async (ctx, next) => {

            // 获取当前账号配置
            const currentAccount = getCurrentAccount();
            if (!currentAccount) {
                ctx.status = 400;
                ctx.body = {
                    error: '未找到当前账号配置',
                    message: '请先登录或配置当前环境账号'
                };
                return;
            }

            // 获取目标URL
            let targetUrl = currentAccount.url;
            if (!targetUrl) {
                // 如果没有url配置，尝试使用host和port构建
                const host = currentAccount.host || 'localhost';
                const targetPort = currentAccount.port || '3000';
                targetUrl = `http://${host}:${targetPort}`;
            }

            if (!targetUrl) {
                ctx.status = 400;
                ctx.body = {
                    error: '目标服务器配置不完整',
                    message: '当前账号配置缺少url或host/port信息'
                };
                return;
            }

            const token = getCurrentToken();
            // 使用 Promise 包装代理操作
            return new Promise((resolve, reject) => {
                ctx.req.url = `/api${ctx.path}`;
                const rawBackendResponse = ctx.query['Raw-Backend-Response'] === 'true';
                // 使用 http-proxy 进行代理
                this.proxy.web(ctx.req, ctx.res, {
                    target: targetUrl,
                    changeOrigin: true,
                    headers: {
                        'x-auth-token': token,
                        token,
                        'Raw-Backend-Response': 'TRUE',
                    }
                }, (err) => {
                    if (err) {
                        console.error('代理转发错误:', err);
                        reject(err);
                    } else {
                        resolve();
                    }
                });
            });
        });

        // 应用路由
        app.use(router.routes()).use(router.allowedMethods());

        return app;
    }

    start() {
        return new Promise((resolve, reject) => {
            // 如果服务器已经在运行，先停止
            if (this.server) {
                this.stop();
            }

            const tryListen = (port) => {
                // 创建 Koa 应用
                this.app = this.setupKoaApp();

                // 启动服务器
                this.server = this.app.listen(port, 'localhost', () => {
                    this.port = port;
                    console.log(`Koa代理服务已启动，端口: ${this.port}`);
                    
                    // 保存实际使用的端口到.env文件
                    savePortToEnv('PROXY_SERVER_PORT', this.port, this.workspacePath);
                    
                    resolve(this.port);
                });

                this.server.on('error', (err) => {
                    // 类型断言来访问 code 属性
                    const nodeErr = err;
                    if (nodeErr.code === 'EADDRINUSE') {
                        console.log(`端口 ${port} 被占用，尝试端口 ${port + 1}`);
                        tryListen(port + 1);
                    } else {
                        reject(err);
                    }
                });
            };

            tryListen(this.port);
        });
    }

    stop() {
        if (this.server) {
            this.server.close(() => {
                console.log('Koa代理服务已停止');
            });
            if (this.proxy) {
                this.proxy.close();
            }
            this.server = null;
            this.app = null;
        }
    }

    getPort() {
        return this.port;
    }
}

// 导出单例
let proxyServerInstance = null;

function getProxyServer() {
    if (!proxyServerInstance) {
        proxyServerInstance = new ProxyServerManager();
    }
    return proxyServerInstance;
}

module.exports = {
    ProxyServerManager,
    getProxyServer
}; 